#ifndef GUDB_TRIGGER_SYSTEM_H
#define GUDB_TRIGGER_SYSTEM_H

#include <stdint.h>
#include <stdbool.h>
#include <time.h>
#include <pthread.h>
#include "../utils/logger.h"
#include "../../include/gudb.h"

#ifdef __cplusplus
extern "C" {
#endif

// Forward declarations
typedef struct trigger_system trigger_system_t;
typedef struct trigger_definition trigger_definition_t;
typedef struct trigger_context trigger_context_t;

// Trigger event types
typedef enum {
    TRIGGER_EVENT_INSERT = 0x01,
    TRIGGER_EVENT_UPDATE = 0x02,
    TRIGGER_EVENT_DELETE = 0x04,
    TRIGGER_EVENT_ALL = 0x07
} trigger_event_t;

// Trigger timing
typedef enum {
    TRIGGER_TIMING_BEFORE = 0,
    TRIGGER_TIMING_AFTER = 1,
    TRIGGER_TIMING_INSTEAD_OF = 2  // For views
} trigger_timing_t;

// Trigger status
typedef enum {
    TRIGGER_STATUS_ACTIVE = 0,
    TRIGGER_STATUS_INACTIVE = 1,
    TRIGGER_STATUS_DISABLED = 2,
    TRIGGER_STATUS_ERROR = 3
} trigger_status_t;

// Trigger action types
typedef enum {
    TRIGGER_ACTION_SQL = 0,         // Execute SQL statements
    TRIGGER_ACTION_FUNCTION = 1,    // Call C function
    TRIGGER_ACTION_SCRIPT = 2       // Execute script (future)
} trigger_action_type_t;

// Row data structure for trigger context
typedef struct trigger_row_data {
    uint32_t column_count;
    char** column_names;
    char** values;
    bool* is_null;
} trigger_row_data_t;

// Trigger execution context
struct trigger_context {
    gudb* database;                     // Database handle
    gudb_txn* transaction;              // Current transaction
    const char* table_name;             // Target table name
    trigger_event_t event;              // Triggering event
    trigger_timing_t timing;            // Trigger timing
    
    // Row data
    trigger_row_data_t* old_row;        // OLD row data (UPDATE/DELETE)
    trigger_row_data_t* new_row;        // NEW row data (INSERT/UPDATE)
    
    // Execution state
    bool should_continue;               // Whether to continue with operation
    bool has_error;                     // Whether an error occurred
    char error_message[512];            // Error message if any
    
    // Performance tracking
    uint64_t start_time_us;             // Trigger start time
    uint64_t execution_time_us;         // Trigger execution time
};

// Trigger function signature
typedef int (*trigger_function_t)(trigger_context_t* context);

// SQL trigger action
typedef struct {
    char* sql_statements;               // SQL statements to execute
    uint32_t statement_count;           // Number of statements
    bool use_transaction;               // Whether to wrap in transaction
} trigger_sql_action_t;

// Function trigger action
typedef struct {
    trigger_function_t function;        // Function pointer
    void* user_data;                    // User data for function
} trigger_function_action_t;

// Trigger action union
typedef union {
    trigger_sql_action_t sql;
    trigger_function_action_t function;
} trigger_action_data_t;

// Trigger definition
struct trigger_definition {
    // Identification
    uint32_t trigger_id;                // Unique trigger ID
    char name[64];                      // Trigger name
    char table_name[64];                // Table name
    
    // Configuration
    trigger_event_t events;             // Event mask (can be multiple)
    trigger_timing_t timing;            // BEFORE/AFTER/INSTEAD_OF
    trigger_status_t status;            // Active/Inactive/Disabled/Error
    
    // Condition
    char* condition;                    // WHEN condition (optional)
    bool has_condition;                 // Whether condition is present
    
    // Action
    trigger_action_type_t action_type;  // Type of action
    trigger_action_data_t action;       // Action data
    
    // Metadata
    time_t created_time;                // When trigger was created
    time_t modified_time;               // When trigger was last modified
    uint64_t execution_count;           // Number of times executed
    uint64_t total_execution_time_us;   // Total execution time
    uint64_t last_execution_time;       // Last execution timestamp
    uint32_t error_count;               // Number of execution errors
    
    // List management
    struct trigger_definition* next;    // Next trigger in list
    struct trigger_definition* prev;    // Previous trigger in list
    
    // Thread safety
    pthread_mutex_t mutex;              // Trigger mutex
};

// Trigger system configuration
typedef struct {
    uint32_t max_triggers;              // Maximum number of triggers
    uint32_t max_sql_length;            // Maximum SQL statement length
    uint32_t max_execution_time_ms;     // Maximum execution time
    bool enable_nested_triggers;       // Allow triggers to fire other triggers
    uint32_t max_nesting_level;         // Maximum nesting level
    bool enable_recursive_triggers;     // Allow recursive trigger execution
    bool enable_performance_tracking;   // Track trigger performance
    bool log_trigger_execution;         // Log trigger executions
} trigger_system_config_t;

// Trigger system statistics
typedef struct {
    uint64_t total_triggers;            // Total number of triggers
    uint64_t active_triggers;           // Number of active triggers
    uint64_t total_executions;          // Total trigger executions
    uint64_t successful_executions;     // Successful executions
    uint64_t failed_executions;         // Failed executions
    uint64_t total_execution_time_us;   // Total execution time
    double avg_execution_time_us;       // Average execution time
    uint64_t max_execution_time_us;     // Maximum execution time
    uint32_t current_nesting_level;     // Current nesting level
    uint64_t nested_executions;         // Number of nested executions
    uint64_t recursive_executions;      // Number of recursive executions
    time_t last_stats_update;           // Last statistics update
} trigger_system_stats_t;

// Main trigger system
struct trigger_system {
    // Configuration
    trigger_system_config_t config;     // System configuration
    trigger_system_stats_t stats;       // System statistics
    gudb* database;                     // Database handle
    logger_t* logger;                   // Logger instance
    
    // Trigger storage
    trigger_definition_t** triggers;    // Trigger array (indexed by ID)
    uint32_t trigger_count;             // Current number of triggers
    uint32_t next_trigger_id;           // Next available trigger ID
    
    // Hash table for fast lookup by table name
    trigger_definition_t** table_triggers[256]; // Hash table buckets
    
    // Event-specific lists for faster execution
    trigger_definition_t* before_insert_triggers;
    trigger_definition_t* after_insert_triggers;
    trigger_definition_t* before_update_triggers;
    trigger_definition_t* after_update_triggers;
    trigger_definition_t* before_delete_triggers;
    trigger_definition_t* after_delete_triggers;
    
    // Thread safety
    pthread_rwlock_t triggers_lock;     // Read-write lock for triggers
    pthread_mutex_t stats_mutex;        // Statistics mutex
    
    // Execution state
    uint32_t current_nesting_level;     // Current nesting level
    bool in_trigger_execution;          // Whether currently executing triggers
    
    // System state
    bool initialized;                   // System initialization status
    time_t start_time;                  // When system was started
};

// Lifecycle functions
trigger_system_t* trigger_system_create(const trigger_system_config_t* config, 
                                        gudb* database);
int trigger_system_init(trigger_system_t* system, logger_t* logger);
void trigger_system_destroy(trigger_system_t* system);

// Trigger definition management
int trigger_system_create_trigger(trigger_system_t* system,
                                 const char* name,
                                 const char* table_name,
                                 trigger_event_t events,
                                 trigger_timing_t timing,
                                 trigger_action_type_t action_type,
                                 const char* action_data,
                                 const char* condition);
int trigger_system_drop_trigger(trigger_system_t* system, const char* name);
trigger_definition_t* trigger_system_find_trigger(trigger_system_t* system, 
                                                  const char* name);
int trigger_system_enable_trigger(trigger_system_t* system, const char* name);
int trigger_system_disable_trigger(trigger_system_t* system, const char* name);

// Trigger execution
int trigger_system_execute_triggers(trigger_system_t* system,
                                   const char* table_name,
                                   trigger_event_t event,
                                   trigger_timing_t timing,
                                   gudb_txn* transaction,
                                   trigger_row_data_t* old_row,
                                   trigger_row_data_t* new_row);

// Row data management
trigger_row_data_t* trigger_row_data_create(uint32_t column_count);
void trigger_row_data_destroy(trigger_row_data_t* row_data);
int trigger_row_data_set_column(trigger_row_data_t* row_data, 
                               uint32_t column_index,
                               const char* column_name,
                               const char* value,
                               bool is_null);
const char* trigger_row_data_get_column(trigger_row_data_t* row_data,
                                       const char* column_name);

// Context management
trigger_context_t* trigger_context_create(gudb* database, 
                                         gudb_txn* transaction,
                                         const char* table_name,
                                         trigger_event_t event,
                                         trigger_timing_t timing);
void trigger_context_destroy(trigger_context_t* context);

// Statistics and monitoring
int trigger_system_get_stats(trigger_system_t* system, 
                            trigger_system_stats_t* stats);
void trigger_system_print_stats(trigger_system_t* system);
int trigger_system_list_triggers(trigger_system_t* system,
                                const char* table_name,
                                trigger_definition_t*** triggers,
                                uint32_t* count);

// Utility functions
const char* trigger_event_to_string(trigger_event_t event);
const char* trigger_timing_to_string(trigger_timing_t timing);
const char* trigger_status_to_string(trigger_status_t status);
uint32_t trigger_table_hash(const char* table_name);

// Default configuration
static inline trigger_system_config_t trigger_system_default_config(void) {
    trigger_system_config_t config = {
        .max_triggers = 1000,               // Maximum triggers
        .max_sql_length = 8192,             // 8KB SQL statements
        .max_execution_time_ms = 5000,      // 5 second timeout
        .enable_nested_triggers = true,     // Allow nesting
        .max_nesting_level = 8,             // Reasonable nesting depth
        .enable_recursive_triggers = false, // Avoid infinite recursion
        .enable_performance_tracking = true,// Track performance
        .log_trigger_execution = true       // Log executions
    };
    return config;
}

// Built-in trigger functions
int trigger_log_changes(trigger_context_t* context);
int trigger_audit_changes(trigger_context_t* context);
int trigger_validate_data(trigger_context_t* context);
int trigger_update_timestamp(trigger_context_t* context);

#ifdef __cplusplus
}
#endif

#endif // GUDB_TRIGGER_SYSTEM_H